/*
 * @(#)GreetingsController.java 2021/1/22
 *
 * Copyright (c) 2010 by rayootech.com. All rights reserved.
 */
package com.nuctech.rsocket.web;

import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Controller;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * RR 请求模型
 *
 * @author lilu
 * @date 2021/1/22 4:36 下午
 * @since 1.0.0
 */
@Slf4j
@Controller
public class GreetingsController {

	/**
	 * RR 请求模型<br>
	 * 客户端调用示例:rsc tcp://localhost:8848/rsocket -r request-response -d 'voishion'<br>
	 * 客户端调用示例:rsc tcp://localhost:8848/rsocket -r request-response -d 'voishion' --debug
	 *
	 * @author lilu
	 * @date 2021/1/22 4:41 下午
	 * @since 1.0.0
	 *
	 * @param payload
	 * @return reactor.core.publisher.Mono<java.lang.String>
	 * @throws
	 */
	@MessageMapping("request-response")
	Mono<String> reqResponse(@Payload String payload) {
		log.info("收到 RR 请求信息: {}", payload);
		return Mono.just("Hello, " + payload);
	}
	/**
	 * FNF 请求模型<br>
	 * 相较于 RR 模型，FNF 不需要返回结果 Mono<br>
	 * 客户端调用示例:rsc tcp://localhost:8848/rsocket -r fire-forget -d 'lilu' -fnf  --debug
	 *
	 * @author lilu
	 * @date 2021/1/22 4:41 下午
	 * @since 1.0.0
	 *
	 * @param payload
	 * @return reactor.core.publisher.Mono<java.lang.Void>
	 * @throws
	 */
	@MessageMapping("fire-forget")
	Mono<Void> fnf(@Payload String payload) {
		log.info("收到 FAF 请求信息: {}", payload);
		return Mono.empty();
	}
	/**
	 * 单向 Stream<br>
	 * 单向 Stream 使用 Flux 作为报文输出，这里演示在收到客户端请求后，每秒返回一次流<br>
	 * 客户端调用示例:rsc tcp://localhost:8848/rsocket -r stream -d 'lilu' -stream --debug
	 *
	 * @author lilu
	 * @date 2021/1/22 4:44 下午
	 * @since 1.0.0
	 *
	 * @param payload
	 * @return reactor.core.publisher.Flux<java.lang.String>
	 * @throws
	 */
	@MessageMapping("stream")
	Flux<String> stream(@Payload String payload) {
		return Flux.interval(Duration.ofSeconds(1)).map(aLong -> payload + LocalDateTime.now());
	}
	/**
	 * 双向 Channel<br>
	 * 双向 channel 的输出和响应都为 Flux<br>
	 * 使用 rsc 进入 channel 并指定交互模式 (注意最后的 - 参数)<br>
	 * 客户端调用示例:rsc tcp://localhost:8848/rsocket -r channel -d -  --channel
	 *
	 * @author lilu
	 * @date 2021/1/22 4:46 下午
	 * @since 1.0.0
	 *
	 * @param settings
	 * @return reactor.core.publisher.Flux<java.lang.String>
	 * @throws
	 */
	@MessageMapping("channel")
	Flux<String> channel(Flux<String> settings) {
		return settings.map(s -> "你好 " + s + LocalDateTime.now());
	}
}
